package com.ozo.easy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ozo.easy.common.model.*;
import com.ozo.easy.common.util.SortUtil;
import com.ozo.easy.common.exception.ServiceException;
import com.ozo.easy.exception.ServiceExceptionEnum;
import com.ozo.easy.pojo.vo.SysNoticeDetailVO;
import com.ozo.easy.entity.SysNotice;
import com.ozo.easy.mapper.SysNoticeMapper;
import com.ozo.easy.pojo.dto.SysNoticeSaveDTO;
import com.ozo.easy.pojo.dto.SysNoticeQueryDTO;
import com.ozo.easy.pojo.vo.SysNoticeVO;
import com.ozo.easy.service.ISysNoticeService;
import com.ozo.easy.pojo.vo.SysDictDataVO;
import com.ozo.easy.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 通知 服务实现类
 *
 * @author ozo
 * @version 1.0
 * @date 2025-02-06 16:35:26
 */
@RequiredArgsConstructor
@Service
public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements ISysNoticeService {

    private final ISysDictTypeService sysDictTypeService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(SysNoticeSaveDTO saveDTO) {
        SysNotice sysNotice = BeanUtil.copyProperties(saveDTO, SysNotice.class);
        Boolean publishFlag = sysNotice.getPublishFlag();
        if (publishFlag) {
            sysNotice.setPublishTime(LocalDateTime.now());
        }
        baseMapper.insert(sysNotice);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void remove(BaseBatchDTO<Long> batchDTO) {
        baseMapper.deleteBatchIds(batchDTO.getIdList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SysNoticeSaveDTO saveDTO) {
        SysNotice sysNotice = baseMapper.selectById(saveDTO.getId());
        if (Objects.isNull(sysNotice)) {
            throw new ServiceException(ServiceExceptionEnum.DATA_NOT_EXISTS);
        }

        sysNotice.setNoticeType(saveDTO.getNoticeType());
        sysNotice.setTitle(saveDTO.getTitle());
        sysNotice.setContent(saveDTO.getContent());
        Boolean publishFlag = saveDTO.getPublishFlag();
        sysNotice.setPublishFlag(publishFlag);
        if (publishFlag && Objects.isNull(sysNotice.getPublishTime())) {
            sysNotice.setPublishTime(LocalDateTime.now());
        }
        baseMapper.updateById(sysNotice);
    }

    @Override
    public PageResult<SysNoticeVO> page(BasePage basePage, SysNoticeQueryDTO queryDTO) {
        Integer pageNum = basePage.getPageNum();
        Integer pageSize = basePage.getPageSize();

        QueryWrapper<SysNotice> queryWrapper = new QueryWrapper<>();
        // 排序
        String order = queryDTO.getOrder();
        if (StrUtil.isBlank(order)) {
            queryWrapper.lambda().orderByDesc(SysNotice::getId);
        } else {
            SortUtil.setSortCondition(queryWrapper, queryDTO.getProp(), order);
        }
        // 条件
        queryWrapper.lambda()
                .eq(StrUtil.isNotBlank(queryDTO.getNoticeType()), SysNotice::getNoticeType, queryDTO.getNoticeType())
                .like(StrUtil.isNotBlank(queryDTO.getTitle()), SysNotice::getTitle, queryDTO.getTitle());
        Page<SysNotice> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);

        PageResult<SysNoticeVO> pageResult = new PageResult<>();
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);
        pageResult.setPage(page.getPages());
        pageResult.setTotal(page.getTotal());
        List<SysNotice> recordList = page.getRecords();

        List<SysNoticeVO> recordVOList = BeanUtil.copyToList(recordList, SysNoticeVO.class);

        if (CollUtil.isNotEmpty(recordVOList)) {
            Map<String, String> noticeTypeMap = sysDictTypeService.listData("NOTICE_TYPE").stream().collect(Collectors.toMap(SysDictDataVO::getDictValue, SysDictDataVO::getDictItem));

            for (SysNoticeVO sysNoticeVO : recordVOList) {
                sysNoticeVO.setNoticeTypeDesc(noticeTypeMap.get(sysNoticeVO.getNoticeType()));
            }
        }

        pageResult.setResults(recordVOList);
        return pageResult;
    }

    @Override
    public List<SysNoticeVO> listNew(Integer limit) {

        QueryWrapper<SysNotice> queryWrapper = new QueryWrapper<>();
        // 排序
        queryWrapper.lambda().orderByDesc(SysNotice::getPublishTime);
        // 条件
        queryWrapper.lambda()
                .eq(SysNotice::getPublishFlag, true);
        Page<SysNotice> page = baseMapper.selectPage(new Page<>(1, limit), queryWrapper);

        List<SysNotice> recordList = page.getRecords();
        List<SysNoticeVO> recordVOList = BeanUtil.copyToList(recordList, SysNoticeVO.class);

        if (CollUtil.isNotEmpty(recordVOList)) {
            Map<String, String> noticeTypeMap = sysDictTypeService.listData("NOTICE_TYPE").stream().collect(Collectors.toMap(SysDictDataVO::getDictValue, SysDictDataVO::getDictItem));

            for (SysNoticeVO sysNoticeVO : recordVOList) {
                sysNoticeVO.setNoticeTypeDesc(noticeTypeMap.get(sysNoticeVO.getNoticeType()));
            }
        }

        return recordVOList;
    }

    @Override
    public SysNoticeDetailVO detail(Long id) {
        SysNotice sysNotice = baseMapper.selectById(id);
        if (Objects.isNull(sysNotice)) {
            throw new ServiceException(ServiceExceptionEnum.DATA_NOT_EXISTS);
        }
        return BeanUtil.copyProperties(sysNotice, SysNoticeDetailVO.class);
    }

}
